Move pipe and socket URL handling to net/url#5215
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5215 +/- ##
==========================================
- Coverage 67.87% 67.82% -0.05%
==========================================
Files 610 610
Lines 62383 62405 +22
==========================================
- Hits 42340 42326 -14
- Misses 16871 16903 +32
- Partials 3172 3176 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
9a83a9d to
24b1dfe
Compare
jhrozek
left a comment
There was a problem hiding this comment.
Two related issues on the Windows side. The af_unix branch of socketURL doesn't actually produce the URL the test fixture asserts, and there's no round-trip test for that branch — which is why the mismatch slipped through. Both should be addressable with a one-char producer change plus the matching round-trip test. Verified locally with Go 1.26.
Rest of the change reads fine.
socketURL on Windows for AF_UNIX paths emitted unix://C:%5Cpath%5Cthv.sock (two slashes) because url.URL.String() only inserts the host/path slash when Host != "". url.Parse then mis-reads the drive letter as host:port and returns "invalid port :%5Cpath%5Cthv.sock", breaking the producer/consumer contract that the rest of this PR establishes. Force the leading slash on Path so String() emits the three-slash form (unix:///C:%5Cpath%5Cthv.sock), which url.Parse accepts and which ParseUnixSocketPath already handles by stripping the synthetic slash before the drive letter. Add TestSocketURL_RoundTrip_AFUnix as a parallel to the existing named-pipe round-trip so future regressions on the Windows AF_UNIX side fail closed in CI rather than only being caught by reading the test fixture row. Addresses review on #5215. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace prefix-and-trim string handling with net/url.Parse on both
the producer (socketURL) and the consumer (HTTPClientForURL,
ParseNamedPipeURL, ParseUnixSocketPath) sides so pipe and socket
addresses round-trip through one library and one set of rules.
socketURL now emits unix:///<path> via (&url.URL{}).String(),
which fixes a real bug on Windows AF_UNIX paths: the previous
concatenation form produced unix://C:\path\thv.sock, which
url.Parse rejects with "invalid port :\\path\\thv.sock". The
round-trip is exercised by new tests on both platforms.
HTTPClientForURL now dispatches on url.Parse + switch u.Scheme,
which gives case-insensitive scheme matching (NPIPE://x routes the
same as npipe://x) for free and matches what the http arm already
does via ValidateLoopbackURL.
ParseNamedPipeURL gains explicit checks that net/url alone cannot
do: a 247-character cap (CreateNamedPipeW's lpName limit minus the
\\.\pipe\ prefix), the legacy reserved Windows device names
(CON, NUL, COM1-9, LPT1-9, ...), and a positive charset of
[A-Za-z0-9._-]+. Names are lowercased via strings.ToLower because
the pipe namespace is case-insensitive at the kernel layer; the
old strings.Contains(name, "..") guard is removed because it
rejected legitimate names like my..api.
ParseUnixSocketPath rejects URLs with non-empty authority, query,
fragment, or userinfo; it also strips the synthetic leading slash
that url.URL inserts in front of Windows drive letters so
unix:///C:%5Cpath%5Cthv.sock round-trips back to C:\path\thv.sock.
Co-authored-by: Cursor <cursoragent@cursor.com>
socketURL on Windows for AF_UNIX paths emitted unix://C:%5Cpath%5Cthv.sock (two slashes) because url.URL.String() only inserts the host/path slash when Host != "". url.Parse then mis-reads the drive letter as host:port and returns "invalid port :%5Cpath%5Cthv.sock", breaking the producer/consumer contract that the rest of this PR establishes. Force the leading slash on Path so String() emits the three-slash form (unix:///C:%5Cpath%5Cthv.sock), which url.Parse accepts and which ParseUnixSocketPath already handles by stripping the synthetic slash before the drive letter. Add TestSocketURL_RoundTrip_AFUnix as a parallel to the existing named-pipe round-trip so future regressions on the Windows AF_UNIX side fail closed in CI rather than only being caught by reading the test fixture row. Addresses review on #5215. Co-authored-by: Cursor <cursoragent@cursor.com>
df44c25 to
b0ffadf
Compare
aponcedeleonch
left a comment
There was a problem hiding this comment.
Approving since Jakub's feedback is also taken care of
jhrozek
left a comment
There was a problem hiding this comment.
Both Windows af_unix findings addressed cleanly in b0ffadf. The producer now emits the three-slash form, the new round-trip test closes the loop, and the expanded doc comment explains why the leading slash is load-bearing. LGTM.
Summary
Follow-up to #5201 (review thread). Stacked on
socker-windows; will rebase ontomainonce #5201 merges. Sibling to #5214.Replaces prefix-and-trim string handling with
net/url.Parseon both producer (socketURL) and consumer (HTTPClientForURL,ParseNamedPipeURL,ParseUnixSocketPath) sides so pipe and socket addresses round-trip through one library and one set of rules.The change includes one real bug fix:
socketURLpreviously emittedunix://C:\path\thv.sockfor Windows AF_UNIX paths, whichurl.Parserejects withinvalid port ":\\path\\thv.sock". The dispatcher only worked because it usedstrings.TrimPrefix. New behavior emitsunix:///C:%5Cpath%5Cthv.sock, which round-trips cleanly. Round-trip is now exercised byTestSocketURL_RoundTrip_UnixandTestSocketURL_RoundTrip_NamedPipe.Other improvements that fall out of the migration:
NPIPE://xroutes the same arm asnpipe://xbecauseurl.Parselowercases the scheme during parsing. Pinned byTestHTTPClientForURL_SchemeDispatchCaseInsensitive.npipe://Thv-APIresolves to\\.\pipe\thv-apiviastrings.ToLower(u.Hostname()); matches the kernel's case-insensitive pipe namespace.CreateNamedPipeWlpNamelimit after the\\.\pipe\prefix).CON,NUL,PRN,AUX,COM1-9,LPT1-9).[A-Za-z0-9._-]+for pipe names — replaces the over-eagerstrings.Contains(name, "..")guard which rejected legitimate names likemy..api.ParseNamedPipeURLrejects pipe URLs with non-empty path / query / fragment / userinfo / port;ParseUnixSocketPathrejects unix URLs with non-empty authority.Addresses inline review comments 3201085366 (
ParseNamedPipeURLmigration), 3201085375 (dispatcher migration), and 3201085383 (socketURL/ParseUnixSocketPathmigration + Windows AF_UNIX bug).Type of change
Test plan
go test ./pkg/api/... ./pkg/server/discovery/...) — green on macOS; new round-trip tests, scheme-case test, reserved-name tests, length-cap test, and shape-rejection cases all pass.task lint-fix— 0 issues.GOOS=windows go vetandGOOS=windows go test -c -o /dev/nullfor both packages — both clean.Does this introduce a user-facing change?
Yes (Windows-only). On Windows,
socketURLfor AF_UNIX paths now emits a percent-encoded URL form. The discovery file is local per-user and overwritten on everythv servestartup, so there is no on-disk migration concern. POSIX paths like/tmp/thv.sockproduce identical output before and after.Made with Cursor